/**
 * @author		Ben Layet
 * @version 	0.2
 * @date		23 Sep 2008
 */
package org.ignoramus.application.model;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Observable;

/**
 * Review Card containing various pieces of information that the user wants to
 * learn.
 * TODO: event forwarding from the log.
 */
public class ReviewCard extends Observable
{
	/** Card title */
	private String							title		= "";

	/** Elements of the card */
	private final Map<String, CardElement>	elementMap	= new LinkedHashMap<String, CardElement>();

	/** Study events log. */
	private final StudyEventsLog			logs		= new StudyEventsLog();

	void addElement(String infoType, CardElement element)
	{
		elementMap.put(infoType, element);
	}

	/**
	 * Gets a piece of information from this card.
	 * 
	 * @param informationType
	 *            the type of information to get.
	 * @return
	 * @throws IgnoramusModelException
	 *             if the information name is not found.
	 */
	public String getInformation(String informationType) throws IgnoramusModelException
	{
		// the return value.
		String ret = elementMap.get(informationType).getValue();
		// check that the info exists
		if (null == ret)
		{
			throw new IgnoramusModelException("There is no information of type '" + informationType + "'.");
		}

		// return the value
		return ret;
	}

	/**
	 * Gets the content of the card.
	 * 
	 * @return the content of the card.
	 */
	public Iterator<CardElement> getElementsIterator()
	{
		// return the value
		return elementMap.values().iterator();
	}

	/**
	 * Sets a piece of information on this card.
	 * 
	 * @param informationType
	 *            the type of information to set.
	 * @param informationValue
	 *            the value to set.
	 */
	public void setInformation(String informationType, String informationValue) throws IgnoramusModelException
	{

		// get the element
		CardElement element = elementMap.get(informationType);
		// check if the infotype is valid.
		if (null == element)
		{
			throw new IgnoramusModelException("The card does not contain any element of type '" + informationType + "'");
		}
		// update the card
		element.setValue(informationValue);
		// notify the listeners
		notifyObservers();
	}

	/**
	 * @return the title
	 */
	public String getTitle()
	{
		return title;
	}

	/**
	 * @param title
	 *            the title to set
	 */
	public void setTitle(String title)
	{
		// update the card
		this.title = title;
		// notify the listeners
		notifyObservers();
	}

	/**
	 * Adds an event in the study log.
	 * 
	 * @param event
	 *            the event.
	 */
	public void logEvent(StudyEvent event)
	{
		logs.put(new Date(), event);
	}

	/**
	 * Adds a card listener.
	 * 
	 * @param l
	 *            the listener.
	 */
	public void addReviewCardListener(ReviewCardListener l)
	{
		super.addObserver(l);
	}

	/**
	 * Removes a card listener.
	 * 
	 * @param l
	 *            the listener.
	 */
	public void removeReviewCardListener(ReviewCardListener l)
	{
		super.deleteObserver(l);
	}
}
